package com.jacksen.demo.view.surface

import android.opengl.GLES20
import android.util.Log
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer

class Triangle {

    private var vertexBuffer: FloatBuffer

    private var mProgram = 0

    // 设置颜色RGBA（red green blue alpha）
    var color = floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f)

    companion object {
        const val COORDS_PER_VERTEX = 3

        const val vertexStride = COORDS_PER_VERTEX * 4

        val triangleCoords = floatArrayOf(
                0.0f, 0.622008459f, 0.0f, // top
                -0.5f, -0.311004243f, 0.0f, // bottom left
                0.5f, -0.311004243f, 0.0f  // bottom right
        )

        private val vertexCount = triangleCoords.size / COORDS_PER_VERTEX


        private const val vertexShaderCode = "uniform mat4 uMVPMatrix;" +
                "attribute vec4 vPosition;" +
                "void main() {" +
                " gl_Position = uMVPMatrix * vPosition;" +
                "}"

        private const val fragmentShaderCode = "precision mediump float;" +
                "uniform vec4 vColor;" +
                "void main() {" +
                " gl_FragColor = vColor;" + "}"
    }

    init {
        val byteBuffer = ByteBuffer.allocateDirect(triangleCoords.size * 4)
        byteBuffer.order(ByteOrder.nativeOrder())
        vertexBuffer = byteBuffer.asFloatBuffer()
        vertexBuffer.put(triangleCoords)
        vertexBuffer.position(0)

        //

        val vertexShader = GLUtil.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode)
        val fragmentShader = GLUtil.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode)

        // 创建一个空的 GLES Program
        mProgram = GLES20.glCreateProgram()
        // 将 vertex shader 绑定到 program 上
        GLES20.glAttachShader(mProgram, vertexShader)
        // 将 fragment shader 绑定到 program 上
        GLES20.glAttachShader(mProgram, fragmentShader)
        // 创建一个可执行的 GLES program
        GLES20.glLinkProgram(mProgram)

        val linkStatus = IntArray(1)
        GLES20.glGetProgramiv(mProgram, GLES20.GL_LINK_STATUS, linkStatus, 0)
        if (linkStatus[0] == GLES20.GL_FALSE) {
            Log.d("GLUtil", "链接失败 -- $mProgram")
            GLES20.glDeleteProgram(mProgram)
        }

        val linkLog = GLES20.glGetProgramInfoLog(mProgram)
        Log.d("GLUtil", "链接log -- $linkLog")

        val validateStatus = IntArray(1)
        GLES20.glValidateProgram(mProgram)
        GLES20.glGetProgramiv(mProgram, GLES20.GL_VALIDATE_STATUS, validateStatus, 0)
        Log.d("GLUtil", "program status: " + validateStatus[0] + "\n验证 program -- " + GLES20.glGetProgramInfoLog(mProgram))

    }

    fun draw(mvpMatrix: FloatArray) {
        // 将 program 添加到 GLES 环境中
        GLES20.glUseProgram(mProgram)
        val positionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition")

        // 准备三角形的坐标数据
        GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer)
        //
        GLES20.glEnableVertexAttribArray(positionHandle)

        //
        val mvpMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix")
        //
        GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)

        // 获取指向 fragment shader 的成员 vColor 的句柄
        val colorHandler = GLES20.glGetUniformLocation(mProgram, "vColor")
        // 设置颜色
        GLES20.glUniform4fv(colorHandler, 1, color, 0)
        // 画三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount)

        // 禁用定点数组
        GLES20.glDisableVertexAttribArray(positionHandle)

    }
}